home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Camelot
/
Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip
/
Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf
/
zc
/
zcc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-08
|
10KB
|
439 lines
/* preprocessor for zc (formerly hcc) , a68k assembler, blink
*/
#include <stdio.h>
#define toupper( x ) ( x > 'Z' ? x - ('a'-'A'): x )
char *malloc();
extern char *getenv();
/* flags if 1 then will allow that operation
* to be performed on a file */
short dozc,doa68k,doblink,dodebug,debug;
short blinkxref,startup,standardblinklib;
doexec( x,errmsg,file )
char x[],*errmsg,*file;
{
if( debug ){
printf("%s\n",x);
return(1);
}
if( ! Execute(x,0L,0L) ){
printf(errmsg,file);
quit();
}
return(1);
}
char libdir[32]; /* librarys' dir */
char cmddir[32]; /* zc,a68k,blink 's dir */
char xrefname[128]; /* blink xref file output */
char blinklibs[128]; /* blink lib direc */
char blinkname[128]; /* output file from a68k */
char a68kname[128]; /* output file from zc */
char zcopts[128]; /* zc options for each phase */
char a68kopts[128]; /* a68k options */
char zctemp[128]; /* CCTEMP dir */
char blinkopts[128]; /* blink options */
char buf[256]; /* command line */
char buf2[256]; /* scratch buf */
/* memory allocation/deallocation routines */
struct mem {
struct mem *prev;
long len;
char *memory;
} *curmem;
char *jmalloc(n)
long n;
{
char *buf;
struct mem *memlist;
buf=(char *)malloc( n+(long )sizeof(struct mem));
if(!buf){
printf("cc: outofmemory\n");
quit();
}
memlist=(struct mem *)buf;
memlist->len=n;
memlist->memory=buf+sizeof(struct mem);
memlist->prev=curmem;
curmem=memlist;
return(memlist->memory);
}
quit()
{
jfree();
exit(0);
}
jfree(){
struct mem *nxmem;
while(curmem != NULL){
nxmem=curmem->prev;
free(curmem); /* frees all the memory we so graciously gobbled up */
curmem=nxmem;
}
}/*end of jfree */
/*********************************************************
Handles file list compiles,assembles,links
**********************************************************/
/* lists of source file names, as well as type of operation */
struct filenm{
struct filenm *next;
struct filenm *prev;
short ab; /* abnormal file name */
short zc; /* 1 if .c file */
short a68k; /* 1 if .s file */
char *name;
}*files,*curfile;
#define copystring( x ) (char *)strcpy( jmalloc( (long )len((char *) x )), x )
/* adds a file to the file list
* computes whether an compile and/or assembly will be done
* also determines whether this is an abnormal file name.
* If so then only a link will be done on the file
*/
struct filenm *addfile(name)
char name[];
{
long l;
struct filenm *newfile;
char *filename;
newfile = (struct filenm *)jmalloc(sizeof(struct filenm));
newfile->prev = curfile;
newfile->next = NULL; /* last file so far */
if(curfile)
curfile->next = newfile;
else
files = newfile;
curfile = newfile;
filename = (char *) copystring( (char *)name);
curfile->name=filename; /* contains the new filename */
l=len(filename);
curfile->ab=0; /* assume it is normal until proven otherwise */
curfile->zc=0;
curfile->a68k=0;
if(filename[l-2] == '.'){
if(filename[l-1]== 'c'){
curfile->zc = 1;
curfile->a68k=1;
}else if (filename[l-1] == 'a' || filename[l-1] == 's'){
curfile->a68k=1;
}else if(filename[l-1] != 'o')
curfile->ab = 1; /* abnormal file name */
}else
curfile->ab = 1; /* abnormal file name */
}/* end of addfile */
long len(x)
char x[];
{
long i;
for(i=0; x[i] != 0 ; i++);
return(i);
}
char *tofiletype(nm,buffer,ext1,ext2)
char nm[],buffer[],ext1[],ext2;
{
long l;
strcpy(buffer,nm);
l=len(buffer);
if(l < 2 || ( buffer[l-2] != '.') ){
strcat(buffer,ext1);
return(buffer);
}
if(ext2)
buffer[l-1] = ext2;
else
buffer[l-2] = '\0'; /* must be executable */
return(buffer);
}/*end of tofiletype */
#define toassem( x ) tofiletype( x ,a68kname,".s ",'s')
#define tolink( x ) tofiletype( x ,blinkname,".o ",'o')
#define toexec( x ) tofiletype( x ,blinkname,".lnk ",'\0')
doerrors()
{
FILE *err;
int nmerrors;
if( (err=fopen("ram:zc.errors","r"))==NULL)
return();
nmerrors=0;
fscanf(err,"%d",&nmerrors);
close(err);
if(nmerrors)
quit();
return(); /* no errors thank goodness */
}
/* this assembles the file */
assemfile(nm,outnm)
char nm[],outnm[];
{
strcpy(buf,cmddir);
strcat(buf,"a68k <* >* ");
strcat(buf,a68kopts);
strcat(buf,"-o");
strcat(buf,outnm);
strcat(buf," ");
strcat(buf,nm);
Chk_Abort();
doexec(buf,"cc: assemble error: %s\n",nm);
}/*end of assemfile*/
/* compiles and/or assembles the files in the file list */
compilefiles(){
struct filenm *file;
char nm[];
file=files;
while(file){
toassem(file->name);/* use this as the input to a68k
* unless updated below */
if(file->zc && dozc ){
strcpy(buf,cmddir);
strcat(buf,"zc >* <* -Eram:zc.errors ");
strcat(buf,zcopts);
strcat(buf," ");
if( (file->a68k && doa68k) || file->ab){
strcat(buf," -O");
if(file->a68k && doa68k)
strcpy(buf2,zctemp); /* use temp file if doing an assemble */
else
buf2[0]='\0';
strcat(buf2,file->name);
strcat(buf,toassem(buf2));/* use designated outputfile */
}
strcat(buf," ");
strcat(buf,file->name);
Chk_Abort();
doexec(buf,"cc: compile error: %s\n",file->name);/* start compiler */
doerrors(); /* read error file to see if any errors */
} /* compiled okay */
if(file->a68k && doa68k){
assemfile(a68kname,tolink(file->name)); /* assemble file */
if(file->zc){ /* if was a c file remove .s file */
strcpy(buf,"c:delete >* <* ");
strcat(buf,a68kname);
Chk_Abort();
doexec(buf,"cc: delete error: %s\n",a68kname);
}
}
file=file->next;/* get next file */
}/* done with this file, compile & assemble next */
}/* done with files */
linkfiles(){
struct filenm *file;
char nm[];
if(!doblink || files == NULL ) return();/* don't do anything if not supposed to */
file=files;
strcpy(buf,cmddir);
strcat(buf,"blink <* >* ");
if(startup){
strcat(buf,libdir);
strcat(buf,"BothStartup.obj ");
}
while(file){
strcat(buf,tolink(file->name));/* build linker list */
file = file->next;
strcat(buf," ");
}
strcat(buf," TO ");
strcat(buf,toexec(files->name));/* use first file name */
strcat(buf," LIB ");
strcat(buf,blinklibs);
if(standardblinklib){
strcat(buf,libdir);
strcat(buf,"amiga.lib ");
}
if(!dodebug)
strcat(buf," NODEBUG ");
if(blinkxref){
strcat(buf," XREF ");
strcat(buf,xrefname);
}
Chk_Abort();
doexec(buf,"cc: linker error:\n",NULL);
printf("cc: executable is %s \n",toexec(files->name));
}/* done linking it */
help()
{
printf("cc: Version 1.0 Preprocessor for \n%s%s%s%s%s%s%s%s%s%s%s%s%s",
" cc: Sozobon-C compiler, \n",
" as: a68k C.Gibbs Motorola Compatible Assembler, and\n",
" blink: Software Distillery Linker \n",
" looks for lib:amiga.lib and lib:BothStartup.obj \n",
" Syntax:\n",
" cc [OPTIONS] <files.c> <files.s> <files.o> \n\n",
" Options:\n",
" -Dxxxx define xxxx, -Uxxxx undefine xxxx\n",
" -C data->chip, -F data->fast\n",
" -S don't use startups, -T don't use amiga.lib\n",
" -A don't assemble, -c don't link\n",
" -Ixxxx include dir, -V printout actions only\n",
" -lxxxx use library lib:xxxx.lib\n");
}
main(argc,argv)
int argc;
char *argv[];
{
int i, l;
char *s;
printf("cc: \n");
if(argc < 2 || argv[1][0] == '?'){
help();
exit(0);
}
startup=standardblinklib=1;/* use BothStartup.obj & amiga.lib */
blinklibs[0]='\0'; /* blink lib direc */
blinkname[0]='\0'; /* output file from a68k */
a68kname[0]='\0'; /* output file from zc */
zcopts[0]='\0'; /* zc options for each phase */
a68kopts[0]='\0'; /* a68k options */
zctemp[0]='\0'; /* CCTEMP dir */
blinkopts[0]='\0'; /* blink options */
buf[0]='\0'; /* command line */
buf2[0]='\0'; /* scratch buf */
dodebug=debug=0;
dozc=doa68k=doblink=1;/* will compile,assem,link unless told otherwise*/
curmem=NULL;/* haven't grabbed any memory yet*/
files=NULL;
curfile=NULL;
blinkxref=0;
strcpy(xrefname," ");
if( getenv("CCLIB") ){
strcpy(libdir," ");
strcat(libdir,getenv("CCLIB")); /* get libdirector */
}else
strcpy(libdir," lib:"); /* default directory */
if( ! getenv("CCEXEC") )
strcpy(cmddir,"c:");
else{
strcpy(cmddir,getenv("CCEXEC")); /*dir for zc,a68k,blink */
}
if( getenv("CCTEMP") ){
strcpy(zctemp,getenv("CCTEMP"));
}else{
printf("cc:Warning, environment variable CCTEMP unset\n Using ram: \n");
strcpy(zctemp,"ram:");
}
if( ! getenv("INCLUDE")){
printf("cc: Warning, environment variable INCLUDE unset\n");
}else{
strcpy(a68kopts," -I");
strcat(a68kopts,getenv("INCLUDE") );
}
for(i = 1; i < argc; i++){/* parse arguments */
Chk_Abort(); /* Do options */
if(argv[i][0] == '+'){
s = argv[i];
switch(s[1]){
default:
printf("cc: No + switches allowed\n");
break;
}
}else if(argv[i][0] == '-' ){
s = argv[i];
switch(s[1]){
case 'A':
case 'a':
doblink = doa68k = 0;
break;
case 'C': /* force data into chip memory */
strcat(zcopts," -C ");
break;
case 'c':
doblink = 0;
break;
case 'd':
case 'D':
strcat(zcopts," -D");
strcat(zcopts,&s[2]);
break;
case 'F':
strcat(zcopts," -F ");
break;
case 'i':
case 'I':
strcat(zcopts," -I");
strcat(zcopts,&s[2]);
break;
case 'l':
strcat(blinklibs," -l");
strcat(blinklibs,&s[2]);
strcat(blinklibs," ");
break;
case 'T':
standardblinklib=0; /* don't use amiga.lib */
break;
case 'S':
startup = 0;/* don't use BothStartup.obj */
break;
case 'u':
case 'U':
strcat(zcopts," -U");
strcat(zcopts,&s[2]);
break;
case 'v':
case 'V':
debug = 1;
break;
default:
printf("bad option: \"%s\"\n", argv[i]);
exit(1);
break;
}
}else /* argument wasn't an option so must be a file */
addfile(argv[i]);/* add filename to list of files */
}/* done with parsing arguments */
compilefiles(); /* compile all the files */
linkfiles(); /* link all the files */
quit();/* cleanup mess and go home */
}